﻿using System;
using System.Collections.Generic;
using System.Text;
using Teamcenter.Services.Internal.Strong.Core._2011_06.ICT;
using Teamcenter.Soa.Client.Model;
using Teamcenter.Soa.Client.Model.Strong;
using Teamcenter.Services.Strong.Workflow;
using Teamcenter.Services.Strong.Workflow._2010_09.Workflow;
using Teamcenter.Services.Strong.Workflow._2008_06.Workflow;
using Teamcenter.Services.Internal.Strong.Core._2011_06.ICT;
namespace TC4T_WinForm
{
    public class EPMTemplateCPPClassNames
    {
        public static readonly string EPMTaskTemplate = "TYPE::EPMTaskTemplate::EPMTaskTemplate::POM_application_object";
        public static readonly string EPMDoTaskTemplate ="TYPE::EPMDoTaskTemplate::EPMTaskTemplate::EPMTaskTemplate";
        public static readonly string EPMReviewTaskTemplate = "TYPE::EPMReviewTaskTemplate::EPMTaskTemplate::EPMTaskTemplate";        
    }

    public enum ItemEMPPropertyNames
    {
        process_stage,
        process_stage_list
    }
    public enum TaskTypePropertiesEnum
    {
        new_tasks_flag,
        new_tasks_count,
        contents,
    }
    public enum InboxSubTypesEnum
    {
        TasksToPerform,
        TasksToTrack,
    }

    public class EPMHelper
    {
        #region EPM模版层级获取
        /// <summary>
        /// 获取所有EMP Process模版
        /// </summary>
        /// <returns></returns>
        private static InvokeICTMethodResponse GetAllEPMTemplates()
        {
            Arg[] args = new Arg[3];
            Arg arg1 = new Arg();
            arg1.Val = "EPMTaskTemplate";
            
            Arg arg2 = new Arg();
            arg2.Val = "TYPE::EPMTaskTemplate::EPMTaskTemplate::POM_application_object";

            Arg arg3 =new Arg();
            arg3.Val = "false";

            args[0] = arg1;args[1]= arg2;args[2]=arg3;
            return TCHelper.InvokeICTMethod("ICCTTaskTemplate", "extentReadyTemplates"
                , args);
        }

        /// <summary>
        /// 获取所有EMP模版<template_name, Uid>
        /// </summary>
        /// <param name="tempname_uid_pair"></param>
        public static void GetAllEPMTemplates(out Dictionary<string,string> tempname_uid_pair)
        {
            InvokeICTMethodResponse response = EPMHelper.GetAllEPMTemplates();
            if (response != null)
            {
                tempname_uid_pair = new Dictionary<string, string>();
                int size = response.ServiceData.sizeOfPlainObjects();
                for (int i = 0; i < size; i++)
                {
                    ModelObject mo = response.ServiceData.GetPlainObject(i);
                    if (mo != null)
                    {
                        string tempname = mo.GetPropertyDisplayableValue("template_name");
                        if (!string.IsNullOrEmpty(tempname))
                        {
                            if (tempname_uid_pair.ContainsKey(tempname))
                                tempname_uid_pair[tempname] = mo.Uid;
                            else
                                tempname_uid_pair.Add(tempname, mo.Uid);
                        }
                    }

                }
            }
            else
            {
                tempname_uid_pair = null;
            }
        }

        /// <summary>
        /// 通用的
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="cppClassType"></param>
        /// <returns></returns>
        private static InvokeICTMethodResponse TemplateGetChildrenInfo(string uid, string cppClassType)
        {
            Arg arg1 = new Arg();
            arg1.Val = "EPMTaskTemplate";
            Arg arg2 = new Arg();
            arg2.Val = cppClassType;//"TYPE::EPMDoTaskTemplate::EPMTaskTemplate::EPMTaskTemplate";
            Arg arg3 = new Arg();
            arg3.Val = uid;

            Arg arg4 = new Arg();
            Structure s1 = new Structure();
            Arg s1Arg1 = new Arg(); s1Arg1.Val = "true";
            Arg s1Arg2 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array array = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array();
            Entry en1 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Entry();
            en1.Val = "subtask_template";
            array.Entries = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Entry[] { en1 };
            s1Arg2.Array = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array[] { array };
            s1.Args = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg[] { s1Arg1, s1Arg2 };
            arg4.Structure = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Structure[] { s1 };
            Arg[] args = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg[4];
            args[0] = arg1; args[1] = arg2; args[2] = arg3; args[3] = arg4;
            return TCHelper.InvokeICTMethod("ICCT", "getChildrenInfo", args);
        }
        public static void TemplateGetChildrenInfo(string uid, string cppClassType, out Dictionary<string, ModelObject> dic)
        {
            InvokeICTMethodResponse response = TemplateGetChildrenInfo(uid, cppClassType);
            if (response != null)
            {
                if (response.ServiceData != null && response.ServiceData.sizeOfPartialErrors() == 0)
                {
                    int numberMo = response.ServiceData.sizeOfPlainObjects();
                    dic = new Dictionary<string, ModelObject>();
                    for (int i = 0; i < numberMo; i++)
                    {
                        ModelObject mo = response.ServiceData.GetPlainObject(i);
                        string tempName = mo.GetPropertyDisplayableValues("template_name")[0];
                        if (tempName != "")
                        {
                            dic.Add(tempName, mo);
                        }
                    }
                    return;
                }
            }
            dic = null;
        }
        #endregion

        #region person group role

        public static List<string> GetAllGroups()
        {
            Arg[] args = new Arg[2];
            Arg arg1 = new Arg(); arg1.Val = "Group";
            Arg arg2 = new Arg(); arg2.Val = "TYPE::Group::Group::POM_group";
            args[0] = arg1; args[1] = arg2;
            InvokeICTMethodResponse response = TCHelper.InvokeICTMethod("ICCTGroup", "getRootGroupAndIconIdList", args);
            if (response != null)
            {

                if (response.Output != null && response.Output.Length > 0)
                {
                    List<string> ret = new List<string>();
                    Arg arg = response.Output[0].Structure[0].Args[1];
                    foreach (Entry e in arg.Array[0].Entries)
                    {
                        ret.Add(e.Val);
                    }
                    return ret;
                }
            }
            return null;
        }

        public static List<string> GetRole(string groupName)
        {
            Arg[] args = new Arg[3];
            Arg arg1 = new Arg(); arg1.Val = "Group";
            Arg arg2 = new Arg(); arg2.Val = "TYPE::Group::Group::POM_group";
            Arg arg3 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            arg3.Val = groupName;
            args[0] = arg1; args[1] = arg2;
            InvokeICTMethodResponse response = TCHelper.InvokeICTMethod("ICCTGroup", "getRoleAndIconIdListForGroup", args);
            if (response != null)
            {
                if (response.Output != null && response.Output.Length > 0)
                {
                    List<string> ret = new List<string>();
                    Arg arg = response.Output[0].Structure[0].Args[1];
                    foreach (Entry e in arg.Array[0].Entries)
                    {
                        ret.Add(e.Val);
                    }
                    return ret;
                }
            }
            return null;
        }

        public List<string> GetMembersOfRole(string groupName ,string roleName)
        {
            Arg[] args = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg[4];
            Arg arg1 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            arg1.Val = "GroupMember";
            Arg arg2 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            arg2.Val = "TYPE::GroupMember::GroupMember::POM_member";

            Arg arg3 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            Structure s1 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Structure();
            Arg s1a1 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            s1a1.Val = "true";
            Arg s1a2 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            s1a2.Val = groupName;
            s1.Args = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg[] { s1a1, s1a2 };
            arg3.Structure = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Structure[] { s1 };

            Arg arg4 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            Structure s2 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Structure();
            Arg s2a1 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            s2a1.Val = "true";
            Arg s2a2 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg();
            s2a2.Val = roleName;
            s2.Args = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Arg[] { s2a1, s2a2 };
            arg4.Structure = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Structure[] { s2 };
            InvokeICTMethodResponse response = TCHelper.InvokeICTMethod("ICCTGroupMember", "getGroupMemberAndIconIdList", args);
            if (response != null)
            {
                if (response.Output != null && response.Output.Length > 0)
                {
                    List<string> ret = new List<string>();
                    Arg arg = response.Output[0].Structure[0].Args[1];
                    foreach (Entry e in arg.Array[0].Entries)
                    {
                        ret.Add(e.Val);
                    }
                    return ret;
                }
            }
            return null;
        }

        public static ModelObject GetRoleByRoleName(string roleName)
        {
            Arg[] args = new Arg[3];
            Arg arg1 = new Arg(); Arg arg2 = new Arg(); Arg arg3 = new Arg();
            arg1.Val = "Role"; arg2.Val = "TYPE::Role::Role::POM_application_object"; arg3.Val = roleName;
            args[0] = arg1; args[1] = arg2; args[2] = arg3;
            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.InvokeICTMethodResponse r_user = TCHelper.InvokeICTMethod("ICCTRole", "find", args);
            if (r_user != null && r_user.ServiceData.sizeOfPartialErrors()==0)
            {
                ModelObject mo = r_user.ServiceData.GetPlainObject(0);
                if (mo != null)
                {
                    return mo;
                }
            }
            return null;
        }

        public static ModelObject GetGroupByGroupName(string group)
        {
            Arg[] args = new Arg[3];
            Arg arg1 = new Arg(); Arg arg2 = new Arg(); Arg arg3 = new Arg();
            arg1.Val = "Group"; arg2.Val = "TYPE::Group::Group::POM_group"; arg3.Val = group;
            args[0] = arg1; args[1] = arg2; args[2] = arg3;
            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.InvokeICTMethodResponse r_user = TCHelper.InvokeICTMethod("ICCTGroup", "find", args);
            if (r_user != null && r_user.ServiceData.sizeOfPartialErrors() == 0)
            {
                ModelObject mo = r_user.ServiceData.GetPlainObject(0);
                if (mo != null)
                {
                    return mo;
                }
            }
            return null;
        }

        public static ModelObject GetUserByLoginName(string loginName)
        {
            Arg[] args = new Arg[3];
            Arg arg1 = new Arg(); Arg arg2 = new Arg(); Arg arg3 = new Arg();
            arg1.Val = "User"; arg2.Val = "TYPE::User::User::POM_user"; arg3.Val = loginName;
            args[0] = arg1; args[1] = arg2; args[2] = arg3;
            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.InvokeICTMethodResponse r_user = TCHelper.InvokeICTMethod("ICCTUser", "find", args);
            if (r_user != null)
            {
                ModelObject mo = r_user.ServiceData.GetPlainObject(0);
                if (mo != null)
                {
                    string name = mo.GetPropertyDisplayableValues("user_name")[0];
                    if (name != null)
                    {
                        return mo;
                    }
                }
            }
            return null;
        }
        #endregion

        #region workflow
        /// #define EPM_target_attachment           1 
        //#define EPM_reference_attachment        3 
        //#define EPM_signoff_attachment          4 
        //#define EPM_release_status_attachment   5 
        //#define EPM_comment_attachment          6 
        //#define EPM_instruction_attachment      7 
        //#define EPM_interprocess_task_attachment    8 
        //#define EPM_project_task_attachment     9 
        public static bool CreateProcess(string itemNo,string templateName,out string msg)
        {
            if (itemNo == "")
            {
                msg = "itemNo不能为空！";
                return false;
            }
            ModelObject mo = TCHelper.QueryItemByItemID(itemNo);
            Dictionary<string, Dictionary<string,Teamcenter.Soa.Client.Model.Property>> dic
                    = TCHelper.GetPropertiesByUids(new string[] { mo.Uid }, new string[] { "process_stage", "process_stage_list" });
            if (dic != null && dic.Keys.Count>0)
            {
                Teamcenter.Soa.Client.Model.Property p = dic[mo.Uid]["process_stage"];
                if (p != null)
                {
                    string[] sarray = p.DisplayableValues;
                    if (sarray != null && sarray.Length >= 0)
                        if (!string.IsNullOrEmpty(sarray[0]))
                        {
                            msg = "已经创建过了！";
                            return false;
                        }
                }
            }
            WorkflowService ws = WorkflowService.getService(MyTCSession.MySessionConnection);
            ContextData cd = new ContextData();
            cd.ProcessTemplate = templateName;
            cd.AttachmentCount = 1;
            cd.Attachments = new string[] { mo.Uid };
            cd.AttachmentTypes = new int[] { 1 };//EPM_target_attachment

            Teamcenter.Services.Strong.Workflow._2008_06.Workflow.InstanceInfo
                instance = ws.CreateInstance(true, null, itemNo + "-name", itemNo + "-subject", itemNo + "-description", cd);
            if (instance != null && instance.ServiceData.sizeOfPartialErrors() == 0)
            {
                //Add Some...
                msg = "创建成功！";
                return true;
            }
            else
            {
                if (instance.ServiceData.sizeOfPartialErrors() > 0)
                {

                    LoggerHelper.LogTCStackError(instance.ServiceData.GetPartialError(0), typeof(WorkFlowForm));
                }
                msg = "错误，请见日志";
                return false;
            }
        }

        /// <summary>
        /// 释放EPM-hold
        /// </summary>
        /// <param name="TaskTemplateUid">为Template本生的uid</param>
        /// <param name="comments"></param>
        /// <returns></returns>
        public static bool ReleaseEMPHold(string TaskTemplateUid,string taskUid,string comments)//EPM-hold
        {
            string EPM_hold_uid = GetEPMTaskTemplateHandler(TaskTemplateUid, "EPM-hold");
            if (EPM_hold_uid == "" || EPM_hold_uid == null)
                return true;
            Arg[] argset = new Arg[5];
            Arg setarg1 = new Arg(); setarg1.Val = "EPMTask";
            Arg setarg2 = new Arg(); setarg2.Val = "TYPE::EPMDoTask::EPMTask::EPMTask";
            Arg setarg3 = new Arg(); setarg3.Val = taskUid;//r_handler.Output[0].Val;

            Arg setarg4 = new Arg(); Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array array1 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array();
            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Entry[] en1s = new Entry[2];
            Entry en11 = new Entry(); en11.Val = "done";
            Entry en12 = new Entry(); en12.Val = "comments";
            en1s[0] = en11; en1s[1] = en12;
            array1.Entries = en1s;
            setarg4.Array = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array[] { array1 };

            Arg setarg5 = new Arg();
            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array array2 = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array();
            Entry en21 = new Entry();
            Structure s1 = new Structure();
            s1.Args = new Arg[2];
            Arg s11 = new Arg(); s11.Val = "true";
            Arg s12 = new Arg(); s12.Val = "true";
            s1.Args[0] = s11; s1.Args[1] = s12;
            en21.Structure = new Structure[] { s1 };

            Entry en22 = new Entry();
            Structure s2 = new Structure();
            s2.Args = new Arg[2];
            Arg s21 = new Arg(); s21.Val = "true";
            Arg s22 = new Arg(); s22.Val = comments;//"";
            s2.Args[0] = s21; s2.Args[1] = s22;
            en22.Structure = new Structure[] { s2 };
            array2.Entries = new Entry[2] { en21, en22 };
            setarg5.Array = new Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.Array[] { array2 };

            argset[0] = setarg1; argset[1] = setarg2; argset[2] = setarg3;
            argset[3] = setarg4; argset[4] = setarg5;
            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.InvokeICTMethodResponse r_setproperty =
        TCHelper.InvokeICTMethod("ICCT", "setProperties", argset);
            if (r_setproperty != null)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取一个Handler的Uid
        /// TaskTemplateUid一定是template本生的Uid，不是对象中实例的Uid
        /// </summary>
        /// <param name="TaskTemplateUid"></param>
        /// <param name="handlerName"></param>
        /// <returns></returns>
        private static string GetEPMTaskTemplateHandler(string TaskTemplateUid, string handlerName)
        {
            Arg[] args1 = new Arg[6];
            Arg arg11 = new Arg(); arg11.Val = "EPMTaskTemplate";
            Arg arg21 = new Arg(); arg21.Val = "TYPE::EPMDoTaskTemplate::EPMTaskTemplate::EPMTaskTemplate";
            Arg arg31 = new Arg(); arg31.Val = TaskTemplateUid;//"wVWFoaBs40fgGC";//dotask.Uid;
            Arg arg41 = new Arg(); arg41.Val = "0";
            Arg arg51 = new Arg(); arg51.Val = "4";
            Arg arg61 = new Arg(); arg61.Val = handlerName;//"EPM-hold";
            args1[0] = arg11; args1[1] = arg21;
            args1[2] = arg31; args1[3] = arg41; args1[4] = arg51; args1[5] = arg61;

            Teamcenter.Services.Internal.Strong.Core._2011_06.ICT.InvokeICTMethodResponse r_handler =
            TCHelper.InvokeICTMethod("ICCTTaskTemplate", "getHandler", args1);
            if (r_handler != null)
            {
                return r_handler.Output[0].Val;
            }
            return null;
        }
        #endregion
        #region user inbox perform track cout
        public static InvokeICTMethodResponse GetUserInboxFolderChildren()
        {
            string uid = MyTCSession.LoginUser.Userinbox.Uid;
            return TCHelper.GetChildrenInfo(uid, "User_Inbox", "TYPE::TaskInbox::User_Inbox::Folder");
        }

        public static InvokeICTMethodResponse GetUserTaskInboxFolderChildren()
        {
            ServiceData user_inbox_sd = GetUserInboxFolderChildren().ServiceData;
            string task_inbox_uid = user_inbox_sd.GetPlainObject(0).Uid;
            if (task_inbox_uid != null && task_inbox_uid.Length > 0)
            {
                return TCHelper.GetChildrenInfo(task_inbox_uid, "TaskInbox",
                    "TYPE::TaskInbox::TaskInbox::Folder");
            }
            return null;
        }

        /// <summary>
        /// 获取perform与track底下的对象们
        /// </summary>
        /// <param name="performs"></param>
        /// <param name="tracks"></param>
        public static void GetTaskPerformAndTaskTrack(out ModelObject[] performs,out ModelObject[] tracks)
        {
            InvokeICTMethodResponse response = GetUserTaskInboxFolderChildren();
            if (response != null)
            {
                ServiceData sd = response.ServiceData;
                ModelObject[] mos = new ModelObject[2];
                mos[0] = sd.GetPlainObject(0);
                mos[1] = sd.GetPlainObject(1);
                ModelObject perform, track;
                if (mos[0].GetPropertyDisplayableValues("object_type")[0] == InboxSubTypesEnum.TasksToPerform.ToString())
                {
                    perform = mos[0];
                    track = mos[1];
                }
                else
                {
                    perform = mos[1];
                    track = mos[0];
                }

                string[] uids = new string[2];
                uids[0] = perform.Uid; uids[1] = track.Uid;

                Dictionary<string, Dictionary<string, Teamcenter.Soa.Client.Model.Property>> dic =
                    TCHelper.GetPropertiesByUids(uids, new string[] { TaskTypePropertiesEnum.new_tasks_flag.ToString(), 
                    TaskTypePropertiesEnum.contents.ToString()});
                if (dic != null)
                {
                    performs = dic[perform.Uid]["contents"].ModelObjectArrayValue;
                    tracks = dic[track.Uid]["contents"].ModelObjectArrayValue;
                }
                else
                {
                    performs = null;
                    tracks = null;
                }
            }
            else
            {
                performs = null;
                tracks = null;
            }
        }
        #endregion
    }
}
